﻿namespace PublicStaticClass
{
    using System;
    using System.Collections.Generic;
    using System.Drawing;
    using System.Drawing.Printing;
    using System.Windows.Forms;

    public class DataGridViewPrinter
    {
        private int BottomMargin;
        private List<float> ColumnsWidth;
        private static int CurrentRow;
        private float CurrentY;
        private bool IsCenterOnPage;
        private bool IsWithPaging;
        private bool IsWithTitle;
        private int LeftMargin;
        private int mColumnPoint;
        private List<int[]> mColumnPoints;
        private List<float> mColumnPointsWidth;
        private int PageHeight;
        private static int PageNumber;
        private int PageWidth;
        private int RightMargin;
        private float RowHeaderHeight;
        private List<float> RowsHeight;
        private DataGridView TheDataGridView;
        private float TheDataGridViewWidth;
        private PrintDocument ThePrintDocument;
        private Color TheTitleColor;
        private Font TheTitleFont;
        private string TheTitleText;
        private int TopMargin;

        public DataGridViewPrinter(DataGridView aDataGridView, PrintDocument aPrintDocument, bool CenterOnPage, bool WithTitle, string aTitleText, Font aTitleFont, Color aTitleColor, bool WithPaging)
        {
            this.TheDataGridView = aDataGridView;
            this.ThePrintDocument = aPrintDocument;
            this.IsCenterOnPage = CenterOnPage;
            this.IsWithTitle = WithTitle;
            this.TheTitleText = aTitleText;
            this.TheTitleFont = aTitleFont;
            this.TheTitleColor = aTitleColor;
            this.IsWithPaging = WithPaging;
            PageNumber = 0;
            this.RowsHeight = new List<float>();
            this.ColumnsWidth = new List<float>();
            this.mColumnPoints = new List<int[]>();
            this.mColumnPointsWidth = new List<float>();
            if (!this.ThePrintDocument.DefaultPageSettings.Landscape)
            {
                this.PageWidth = this.ThePrintDocument.DefaultPageSettings.PaperSize.Width;
                this.PageHeight = this.ThePrintDocument.DefaultPageSettings.PaperSize.Height;
            }
            else
            {
                this.PageHeight = this.ThePrintDocument.DefaultPageSettings.PaperSize.Width;
                this.PageWidth = this.ThePrintDocument.DefaultPageSettings.PaperSize.Height;
            }
            this.LeftMargin = this.ThePrintDocument.DefaultPageSettings.Margins.Left;
            this.TopMargin = this.ThePrintDocument.DefaultPageSettings.Margins.Top;
            this.RightMargin = this.ThePrintDocument.DefaultPageSettings.Margins.Right;
            this.BottomMargin = this.ThePrintDocument.DefaultPageSettings.Margins.Bottom;
            CurrentRow = 0;
        }

        private void Calculate(Graphics g)
        {
            if (PageNumber == 0)
            {
                int num4;
                SizeF ef = new SizeF();
                this.TheDataGridViewWidth = 0f;
                for (int i = 0; i < this.TheDataGridView.Columns.Count; i++)
                {
                    Font font = this.TheDataGridView.ColumnHeadersDefaultCellStyle.Font;
                    if (font == null)
                    {
                        font = this.TheDataGridView.DefaultCellStyle.Font;
                    }
                    ef = g.MeasureString(this.TheDataGridView.Columns[i].HeaderText, font);
                    float width = ef.Width;
                    this.RowHeaderHeight = ef.Height;
                    for (int j = 0; j < this.TheDataGridView.Rows.Count; j++)
                    {
                        font = this.TheDataGridView.Rows[j].DefaultCellStyle.Font;
                        if (font == null)
                        {
                            font = this.TheDataGridView.DefaultCellStyle.Font;
                        }
                        ef = g.MeasureString("Anything", font);
                        this.RowsHeight.Add(ef.Height);
                        ef = g.MeasureString(this.TheDataGridView.Rows[j].Cells[i].EditedFormattedValue.ToString(), font);
                        if (ef.Width > width)
                        {
                            width = ef.Width;
                        }
                    }
                    if (this.TheDataGridView.Columns[i].Visible)
                    {
                        this.TheDataGridViewWidth += width;
                    }
                    this.ColumnsWidth.Add(width);
                }
                int num5 = 0;
                for (num4 = 0; num4 < this.TheDataGridView.Columns.Count; num4++)
                {
                    if (this.TheDataGridView.Columns[num4].Visible)
                    {
                        num5 = num4;
                        break;
                    }
                }
                int count = this.TheDataGridView.Columns.Count;
                for (num4 = this.TheDataGridView.Columns.Count - 1; num4 >= 0; num4--)
                {
                    if (this.TheDataGridView.Columns[num4].Visible)
                    {
                        count = num4 + 1;
                        break;
                    }
                }
                float theDataGridViewWidth = this.TheDataGridViewWidth;
                float num8 = (this.PageWidth - this.LeftMargin) - this.RightMargin;
                if (this.TheDataGridViewWidth > num8)
                {
                    theDataGridViewWidth = 0f;
                    for (num4 = 0; num4 < this.TheDataGridView.Columns.Count; num4++)
                    {
                        if (this.TheDataGridView.Columns[num4].Visible)
                        {
                            theDataGridViewWidth += this.ColumnsWidth[num4];
                            if (theDataGridViewWidth > num8)
                            {
                                theDataGridViewWidth -= this.ColumnsWidth[num4];
                                this.mColumnPoints.Add(new int[] { num5, count });
                                this.mColumnPointsWidth.Add(theDataGridViewWidth);
                                num5 = num4;
                                theDataGridViewWidth = this.ColumnsWidth[num4];
                            }
                        }
                        count = num4 + 1;
                    }
                }
                this.mColumnPoints.Add(new int[] { num5, count });
                this.mColumnPointsWidth.Add(theDataGridViewWidth);
                this.mColumnPoint = 0;
            }
        }

        public bool DrawDataGridView(Graphics g)
        {
            try
            {
                this.Calculate(g);
                this.DrawHeader(g);
                return this.DrawRows(g);
            }
            catch (Exception exception)
            {
                MessageBox.Show("Operation failed: " + exception.Message.ToString(), Application.ProductName + " - Error", MessageBoxButtons.OK, MessageBoxIcon.Hand);
                return false;
            }
        }

        private void DrawHeader(Graphics g)
        {
            this.CurrentY = this.TopMargin;
            if (this.IsWithPaging)
            {
                PageNumber++;
                string text = "第 " + PageNumber.ToString() + " 页";
                StringFormat format = new StringFormat();
                format.Trimming = StringTrimming.Word;
                format.FormatFlags = StringFormatFlags.NoClip | StringFormatFlags.LineLimit | StringFormatFlags.NoWrap;
                format.Alignment = StringAlignment.Far;
                Font font = new Font("黑体", 8f, FontStyle.Regular, GraphicsUnit.Point);
                RectangleF layoutRectangle = new RectangleF((float) this.LeftMargin, this.CurrentY, (this.PageWidth - this.RightMargin) - this.LeftMargin, g.MeasureString(text, font).Height);
                g.DrawString(text, font, new SolidBrush(Color.Black), layoutRectangle, format);
                this.CurrentY += g.MeasureString(text, font).Height;
            }
            if (this.IsWithTitle)
            {
                StringFormat format2 = new StringFormat();
                format2.Trimming = StringTrimming.Word;
                format2.FormatFlags = StringFormatFlags.NoClip | StringFormatFlags.LineLimit | StringFormatFlags.NoWrap;
                if (this.IsCenterOnPage)
                {
                    format2.Alignment = StringAlignment.Center;
                }
                else
                {
                    format2.Alignment = StringAlignment.Near;
                }
                RectangleF ef2 = new RectangleF((float) this.LeftMargin, this.CurrentY, (this.PageWidth - this.RightMargin) - this.LeftMargin, g.MeasureString(this.TheTitleText, this.TheTitleFont).Height);
                g.DrawString(this.TheTitleText, this.TheTitleFont, new SolidBrush(this.TheTitleColor), ef2, format2);
                this.CurrentY += g.MeasureString(this.TheTitleText, this.TheTitleFont).Height;
            }
            float leftMargin = this.LeftMargin;
            if (this.IsCenterOnPage)
            {
                leftMargin += (((this.PageWidth - this.RightMargin) - this.LeftMargin) - this.mColumnPointsWidth[this.mColumnPoint]) / 2f;
            }
            Color foreColor = this.TheDataGridView.ColumnHeadersDefaultCellStyle.ForeColor;
            if (foreColor.IsEmpty)
            {
                foreColor = this.TheDataGridView.DefaultCellStyle.ForeColor;
            }
            SolidBrush brush = new SolidBrush(foreColor);
            Color backColor = this.TheDataGridView.ColumnHeadersDefaultCellStyle.BackColor;
            if (backColor.IsEmpty)
            {
                backColor = this.TheDataGridView.DefaultCellStyle.BackColor;
            }
            SolidBrush brush2 = new SolidBrush(backColor);
            Pen pen = new Pen(this.TheDataGridView.GridColor, 1f);
            Font font2 = this.TheDataGridView.ColumnHeadersDefaultCellStyle.Font;
            if (font2 == null)
            {
                font2 = this.TheDataGridView.DefaultCellStyle.Font;
            }
            RectangleF rect = new RectangleF(leftMargin, this.CurrentY, this.mColumnPointsWidth[this.mColumnPoint], this.RowHeaderHeight);
            g.FillRectangle(brush2, rect);
            StringFormat format3 = new StringFormat();
            format3.Trimming = StringTrimming.Word;
            format3.FormatFlags = StringFormatFlags.NoClip | StringFormatFlags.LineLimit | StringFormatFlags.NoWrap;
            for (int i = (int) this.mColumnPoints[this.mColumnPoint].GetValue(0); i < ((int) this.mColumnPoints[this.mColumnPoint].GetValue(1)); i++)
            {
                if (this.TheDataGridView.Columns[i].Visible)
                {
                    float width = this.ColumnsWidth[i];
                    if (this.TheDataGridView.ColumnHeadersDefaultCellStyle.Alignment.ToString().Contains("Right"))
                    {
                        format3.Alignment = StringAlignment.Far;
                    }
                    else if (this.TheDataGridView.ColumnHeadersDefaultCellStyle.Alignment.ToString().Contains("Center"))
                    {
                        format3.Alignment = StringAlignment.Center;
                    }
                    else
                    {
                        format3.Alignment = StringAlignment.Near;
                    }
                    RectangleF ef4 = new RectangleF(leftMargin, this.CurrentY, width, this.RowHeaderHeight);
                    g.DrawString(this.TheDataGridView.Columns[i].HeaderText, font2, brush, ef4, format3);
                    if (this.TheDataGridView.RowHeadersBorderStyle != DataGridViewHeaderBorderStyle.None)
                    {
                        g.DrawRectangle(pen, leftMargin, this.CurrentY, width, this.RowHeaderHeight);
                    }
                    leftMargin += width;
                }
            }
            this.CurrentY += this.RowHeaderHeight;
        }

        private bool DrawRows(Graphics g)
        {
            Pen pen = new Pen(this.TheDataGridView.GridColor, 1f);
            StringFormat format = new StringFormat();
            format.Trimming = StringTrimming.Word;
            format.FormatFlags = StringFormatFlags.LineLimit | StringFormatFlags.NoWrap;
            while (CurrentRow < this.TheDataGridView.Rows.Count)
            {
                if (this.TheDataGridView.Rows[CurrentRow].Visible)
                {
                    SolidBrush brush2;
                    SolidBrush brush3;
                    Font font = this.TheDataGridView.Rows[CurrentRow].DefaultCellStyle.Font;
                    if (font == null)
                    {
                        font = this.TheDataGridView.DefaultCellStyle.Font;
                    }
                    Color foreColor = this.TheDataGridView.Rows[CurrentRow].DefaultCellStyle.ForeColor;
                    if (foreColor.IsEmpty)
                    {
                        foreColor = this.TheDataGridView.DefaultCellStyle.ForeColor;
                    }
                    SolidBrush brush = new SolidBrush(foreColor);
                    Color backColor = this.TheDataGridView.Rows[CurrentRow].DefaultCellStyle.BackColor;
                    if (backColor.IsEmpty)
                    {
                        brush2 = new SolidBrush(this.TheDataGridView.DefaultCellStyle.BackColor);
                        brush3 = new SolidBrush(this.TheDataGridView.AlternatingRowsDefaultCellStyle.BackColor);
                    }
                    else
                    {
                        brush2 = new SolidBrush(backColor);
                        brush3 = new SolidBrush(backColor);
                    }
                    float leftMargin = this.LeftMargin;
                    if (this.IsCenterOnPage)
                    {
                        leftMargin += (((this.PageWidth - this.RightMargin) - this.LeftMargin) - this.mColumnPointsWidth[this.mColumnPoint]) / 2f;
                    }
                    RectangleF rect = new RectangleF(leftMargin, this.CurrentY, this.mColumnPointsWidth[this.mColumnPoint], this.RowsHeight[CurrentRow]);
                    if ((CurrentRow % 2) == 0)
                    {
                        g.FillRectangle(brush2, rect);
                    }
                    else
                    {
                        g.FillRectangle(brush3, rect);
                    }
                    for (int i = (int) this.mColumnPoints[this.mColumnPoint].GetValue(0); i < ((int) this.mColumnPoints[this.mColumnPoint].GetValue(1)); i++)
                    {
                        if (this.TheDataGridView.Columns[i].Visible)
                        {
                            if (this.TheDataGridView.Columns[i].DefaultCellStyle.Alignment.ToString().Contains("Right"))
                            {
                                format.Alignment = StringAlignment.Far;
                            }
                            else if (this.TheDataGridView.Columns[i].DefaultCellStyle.Alignment.ToString().Contains("Center"))
                            {
                                format.Alignment = StringAlignment.Center;
                            }
                            else
                            {
                                format.Alignment = StringAlignment.Near;
                            }
                            float width = this.ColumnsWidth[i];
                            RectangleF layoutRectangle = new RectangleF(leftMargin, this.CurrentY, width, this.RowsHeight[CurrentRow]);
                            g.DrawString(this.TheDataGridView.Rows[CurrentRow].Cells[i].EditedFormattedValue.ToString(), font, brush, layoutRectangle, format);
                            if (this.TheDataGridView.CellBorderStyle != DataGridViewCellBorderStyle.None)
                            {
                                g.DrawRectangle(pen, leftMargin, this.CurrentY, width, this.RowsHeight[CurrentRow]);
                            }
                            leftMargin += width;
                        }
                    }
                    this.CurrentY += this.RowsHeight[CurrentRow];
                    if (((int) this.CurrentY) > ((this.PageHeight - this.TopMargin) - this.BottomMargin))
                    {
                        CurrentRow++;
                        return true;
                    }
                }
                CurrentRow++;
            }
            CurrentRow = 0;
            this.mColumnPoint++;
            if (this.mColumnPoint == this.mColumnPoints.Count)
            {
                this.mColumnPoint = 0;
                return false;
            }
            return true;
        }
    }
}

